<template>
  <div style="width:100%;height:100%;position: relative" ref="mapBox">
    <!--    展开图层 E-->
    <!--    地图弹窗B-->
    <div style='display: none'>
      <div id="popup" class="ol-popup">
        <a href="#" id="popup-closer" class="ol-popup-closer" @click="closer"></a>
        <div id="popup-content" ref="content" class="zdyss">
          <div>
            <img src="/static/images/niao.png" alt="">
          </div>
          <div>
            <span>{{obj.name}}</span>
            <span>档案号：{{obj.number}}</span>
          </div>
        </div>
      </div>
    </div>
    <!--    地图弹窗E-->
  </div>
</template>

<script>
  import "ol/ol.css";
  import olMap from "ol/Map";
  import View from "ol/View";
  import VectorSources from 'ol/source/Vector';
  import {Vector as VectorSource, XYZ} from "ol/source";
  import * as olProj from "ol/proj";
  import {Heatmap as HeatmapLayer, Image as ImageLayer, Tile as TileLayer, Vector as VectorLayer} from "ol/layer";
  import ImageWMS from 'ol/source/ImageWMS';
  import WMTS from 'ol/source/WMTS';
  import WMTSTileGrid from 'ol/tilegrid/WMTS';
  import {Circle as CircleStyle, Fill, Icon, Stroke, Style, Text} from 'ol/style';
  import GeoJSON from "ol/format/GeoJSON";
  import {getTopLeft, getWidth} from 'ol/extent.js';
  import {defaults as defaultControls} from 'ol/control';
  import Overlay from 'ol/Overlay';
  import api from '../utils/api'
  import http from '../utils/http'

  export default {
    data() {
      return {
        Map: null,
        center: [],
        level: 8,
        totalMap: {},
        vectorSource: null,//图层源
        areaId: "",
        lonlat: [],
        puplay: null,
        obj: {
          name: "",
          number: ""
        }
      };
    },
    created() {
      this.areaId = window.sessionStorage.getItem('areaId');
    },
    mounted() {
      //监测页面变化
      let elementResizeDetectorMaker = require("element-resize-detector");//导入
      // 创建实例
      let erd = elementResizeDetectorMaker();
      // 创建实例带参
      let vm = this;
      //监听id为test的元素 大小变化
      erd.listenTo(this.$el, function (element) {
        if (vm.Map != null) {
          vm.Map.updateSize();
        }
      });
      //监测页面变化
    },
    methods: {
      //创建地图andcesium
      creationMap() {

        //创建弹窗
        let container = document.getElementById('popup');
        this.puplay = new Overlay({
          element: container,
          autoPan: true,
          autoPanAnimation: {
            duration: 250
          }
        });

        let _this = this;
        (async function f() {
          let res = await http.get(api.areaInfo + '?areaId=' + _this.areaId)
          if (res.data.code == '200') {
            let o = res.data.data;
            _this.Map = new olMap({
              target: _this.$el,
              layers: [],
              overlays: [_this.puplay],
              controls: defaultControls({
                attribution: false,
                zoom: false,
                rotate: false
              }).extend([]),
              view: new View({
                //设置中心点
                center: olProj.fromLonLat([o.centreLon, o.centreLat]),
                zoom: 12,
              })
            });
            //创建图层对象
            _this.totalMap["bsaeMap"] = new TileLayer({
              source: new XYZ({
                url: 'http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f24cec70606332017dcd39a4fb60dd11'
              })
            })
            //添加底图
            _this.Map.addLayer(_this.totalMap["bsaeMap"]);
            //添加默认功能区划
            _this.drawWMS(o.layers[0].id, o.layers[0].layerUrl, o.layers[0].layerName, o.layers[0].styleId, o.layers[0].cql);


            _this.Map.on('singleclick', function (event) {
              let feature = _this.Map.forEachFeatureAtPixel(event.pixel,
                function (feature, layer) {
                  return feature;
                });
              if (typeof (feature) != "undefined") {
                if (feature.get("data") != undefined) {
                  let data = feature.get("data");
                  _this.obj = Object.assign({}, data);
                  let coordinate = olProj.fromLonLat([data.lon, data.lat]);
                  _this.puplay.setPosition(coordinate);
                }
              }
            });

          }
        })()
      },
      //绘制wms类型
      drawWMS(item, url, name, styleId, cql) {
        if (typeof (this.totalMap[item]) == "undefined") {
          let params = {
            'LAYERS': name,
            'STYLES': styleId,
            'CQL_FILTER': "[" + cql + "]"
          };

          this.totalMap[item] = new ImageLayer({
            source: new ImageWMS({
              url: url,
              params: params,
              serverType: 'geoserver'
            })
          })
          this.Map.addLayer(this.totalMap[item]);
        }
      },
      //绘制XYZ类型
      drawXYZ(item, url) {
        if (typeof (this.totalMap[item]) == "undefined") {
          this.totalMap[item] = new TileLayer({
              source: new XYZ({
                url: url
              })
            },
          )
          this.Map.addLayer(this.totalMap[item])
        }
      },
      //绘制热力图
      drawHeatMap(uniqueId, fenbu) {
        //判断是否已经存在相同id的图层 如果有删掉，再重新绘制
        if (typeof (this.totalMap[uniqueId]) != "undefined") {
          this.Map.removeLayer(this.totalMap[uniqueId]);
          delete this.totalMap[uniqueId];
        }
        console.log(fenbu);
        /**geojson数据 绘制热力图**/
        let geojsonObject = {
          'type': 'FeatureCollection',
          "crs": {
            "type": "name",
            "properties": {
              "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
            }
          },
          'features': []
        };
        for (var i = 0; i < fenbu.length; i++) {
          //console.log($scope.oneData.fenbu[i])
          var feature = {
            'type': 'Feature',
            'geometry': {
              'type': 'Point',
              'coordinates': olProj.transform(fenbu[i], 'EPSG:4326', 'EPSG:3857')
            }
          };
          geojsonObject.features.push(feature);
        }

        let heatmap = new HeatmapLayer({
          source: new VectorSources({
            features: (new GeoJSON()).readFeatures(geojsonObject)
          }),
          blur: parseInt(10, 10),
          radius: parseInt(5, 10)
        });
        this.totalMap[uniqueId] = heatmap;
        this.Map.addLayer(heatmap);
      },
      //绘制wmts类型
      drawWMTS(item, url, layer, matrixSet, format, style) {
        if (typeof (this.totalMap[item]) == "undefined") {
          var projection = olProj.get('EPSG:4326');
          var projectionExtent = projection.getExtent();
          var size = getWidth(projectionExtent) / 256;
          var resolutions = new Array(14);
          var matrixIds = new Array(14);
          for (var z = 0; z < 14; ++z) {
            resolutions[z] = size / Math.pow(2, z);
            matrixIds[z] = z;
          }
          this.totalMap[item] = new TileLayer({
            source: new WMTS({
              url: url,
              layer: layer,
              matrixSet: matrixSet,
              format: format,
              projection: projection,
              tileGrid: new WMTSTileGrid({
                origin: getTopLeft(projectionExtent),
                resolutions: resolutions,
                matrixIds: matrixIds
              }),
              style: style
            })
          });
          this.Map.addLayer(this.totalMap[item])
        }
      },
      //绘制geojson类型
      previewshape(data, id) {
        let vm = this;
        //判断是否已经存在相同id的图层 如果有删掉，再重新绘制
        if (typeof (this.totalMap[id]) != "undefined") {
          this.Map.removeLayer(this.totalMap[id]);
          delete this.totalMap[id];
        }
        let styleFunction = function () {
          return function (feature, resolution) {
            //点
            if (feature.getGeometry().getType() == 'Point') {
              if (feature.get('fillColor').indexOf('#') != -1) {
                var point = new Style({
                  image: new CircleStyle({
                    radius: feature.get("radius"),
                    fill: new Fill({
                      color: feature.get("fillColor")
                    }),
                    stroke: new Stroke({
                      color: feature.get("borderColor"),
                      width: feature.get("size")
                    })
                  }),
                  text: new Text({
                    font: '12px Calibri,sans-serif',
                    text: feature.get('text'),
                    fill: new Fill({
                      color: feature.get('fillColor')
                    }),
                    offsetY: 15,
                    stroke: new Stroke({
                      color: 'white',
                      width: 1
                    }),
                  })
                })
              } else {
                var point = new Style({
                  image: vm.addImage(feature, resolution),
                  text: new Text({
                    font: '12px Calibri,sans-serif',
                    text: feature.get('text'),
                    fill: new Fill({
                      color: feature.get('fillColor')
                    }),
                    offsetY: 15,
                    stroke: new Stroke({
                      color: 'white',
                      width: 1
                    }),
                  })
                })
              }
              return [point]
            }
            if (feature.getGeometry().getType() == 'MultiPoint') {
              var MultiPoint = new Style({
                image: new CircleStyle({
                  radius: 5,
                  fill: new Fill({
                    color: feature.get("fillColor")
                  }),
                  stroke: new Stroke({
                    color: feature.get("borderColor"),
                    width: feature.get("size")
                  })
                }),
                text: new Text({
                  font: '12px Calibri,sans-serif',
                  text: feature.get('text'),
                  fill: new Fill({
                    color: feature.get('fillColor')
                  }),
                  offsetY: 15,
                  stroke: new Stroke({
                    color: 'white',
                    width: 1
                  }),
                })
              })
              return [MultiPoint]
            }
            //面
            if (feature.getGeometry().getType() == 'MultiPolygon') {
              var MultiPolygon = new Style({
                stroke: new Stroke({
                  color: feature.get('borderColor'),
                  width: feature.get("size")
                }),
                fill: new Fill({
                  color: feature.get("fillColor")
                }),
                text: new Text({
                  font: '16px Calibri,sans-serif',
                  text: feature.get('text'),
                  fill: new Fill({
                    color: feature.get('textColor')
                  }),
                  stroke: new Stroke({
                    color: feature.get('textColor'),
                    width: 1
                  })
                })
              })
              return [MultiPolygon]
            }
            if (feature.getGeometry().getType() == 'Polygon') {
              var Polygon = new Style({
                stroke: new Stroke({
                  color: feature.get('borderColor'),
                  width: feature.get("size")
                }),
                fill: new Fill({
                  color: feature.get("fillColor")
                }),
                text: new Text({
                  font: '12px Calibri,sans-serif',
                  text: feature.get('text'),
                  fill: new Fill({
                    color: feature.get('borderColor')
                  }),
                  stroke: new Stroke({
                    color: 'white',
                    width: 3
                  }),
                })
              })
              return [Polygon]
            }
            //线
            if (feature.getGeometry().getType() == 'LineString') {
              var LineString = new Style({
                stroke: new Stroke({
                  color: feature.get('borderColor'),
                  width: feature.get("size") + 3
                }),
                text: new Text({
                  font: '12px Calibri,sans-serif',
                  text: feature.get('text'),
                  fill: new Fill({
                    color: 'white'
                  }),
                  stroke: new Stroke({
                    color: 'block',
                    width: 2
                  }),
                })
              })
              return [LineString]
            }
            //多线
            if (feature.getGeometry().getType() == 'MultiLineString') {
              var MultiLineString = new Style({
                stroke: new Stroke({
                  color: feature.get('borderColor'),
                  width: feature.get("size") + 3
                }),
                text: new Text({
                  font: '12px Calibri,sans-serif',
                  text: feature.get('text'),
                  fill: new Fill({
                    color: 'white'
                  }),
                  stroke: new Stroke({
                    color: 'block',
                    width: 2
                  }),
                })
              })
              return [MultiLineString]
            }
          }
        };
        let geojsonObject = {
          'type': 'FeatureCollection',
          'crs': {
            'type': 'name',
            'properties': {
              'name': 'EPSG:4326'
            }
          },
          'features': []
        };
        this.vectorSource = new VectorSource({
          features: (new GeoJSON(
            {
              defaultDataProjection: 'EPSG:4326',
              featureProjection: 'EPSG:3857'
            }
          )).readFeatures(geojsonObject)
        });
        this.totalMap[id] = new VectorLayer({
          source: this.vectorSource,
          style: styleFunction()
        });
        let sources = this.totalMap[id].getSource();
        data.forEach((e => {
          sources.addFeatures(
            (new GeoJSON({
              defaultDataProjection: 'EPSG:4326',
              featureProjection: 'EPSG:3857'
            })).readFeatures({
              "id": e.id,
              "properties": {
                "name": e.name,
                "borderColor": e.borderColor,
                "fillColor": e.fillColor,
                "iconSrc": e.iconSrc,
                "size": e.size,
                "radius": 6,
                "text": e.name,
                "textColor": e.textColor,
                "data": e.data
              },
              'type': 'Feature',
              'geometry': e.geojson
            }))
        }));
        this.totalMap[id].set("altitudeMode", "clampToGround");
        this.Map.addLayer(this.totalMap[id]);
      },
      //点类型绘制图标 需要定位图标位置
      //地图图标位置处理函数
      addImage(feature, resolution) {
        let src = feature.get('iconSrc');
        let anchor = [0, 1];
        //根据图标文件名 设置定位点  地图上放置的图标更改文件名即可保持一致
        if (src != '') {
          if (src.indexOf('anchor_bottom_center') != -1) {
            anchor = [0.5, 1];
          } else if (src.indexOf('anchor_bottom_left') != -1) {
            anchor = [0, 1];
          } else if (src.indexOf('anchor_bottom_right') != -1) {
            anchor = [1, 1];
          } else if (src.indexOf('anchor_center_center') != -1) {
            anchor = [0.5, 0.5];
          } else if (src.indexOf('anchor_top_center') != -1) {
            anchor = [0.5, 0];
          } else if (src.indexOf('anchor_top_left') != -1) {
            anchor = [0, 0];
          } else if (src.indexOf('anchor_top_right') != -1) {
            anchor = [1, 0];
          }
          return new Icon({
            src: feature.get('iconSrc'),
            anchor: anchor,
          });
        }
      },
      //删除
      delMap(id) {
        if (typeof (this.totalMap[id]) != "undefined") {
          this.Map.removeLayer(this.totalMap[id]);
          delete this.totalMap[id];
        }
      },
      //关闭弹窗
      closer() {
        let closer = document.getElementById('popup-closer');
        this.puplay.setPosition(undefined);
        closer.blur();
        return false
      },
    }
  };
</script>

<style scoped>
  .zdyss {
    width: 3rem;
    height: .8rem;
    display: flex;
    flex-shrink: 0;
  }

  .zdyss > div:nth-child(1) {
    flex: 2;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .zdyss > div:nth-child(1) img {
    width: .4rem;
    height: .4rem;
  }

  .zdyss > div:nth-child(2) {
    flex: 8;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    font-size: .18rem;
  }
</style>
<style>
  .ol-popup {
    /*padding: .15rem;*/
    border-radius: 8px;
    box-shadow: 0 3px 10px 0;
    background-color: #fff;
    position: absolute;
    bottom: 12px;
    right: -50px;
    /*overflow: hidden;*/
  }

  .ol-popup:after, .ol-popup:before {
    top: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
  }

  .ol-popup:after {
    border-top-color: white;
    border-width: 10px;
    right: 40px;
    margin-left: -10px;
  }

  .ol-popup:before {
    border-top-color: #cccccc;
    border-width: 11px;
    right: 40px;
    margin-left: -11px;
  }

  .ol-popup-closer {
    text-decoration: none;
    position: absolute;
    top: 2px;
    right: 8px;
  }

  .ol-popup-closer:after {
    content: "✖";
  }

  #popup-content {
    /*margin-top: 10px;*/
    overflow: hidden;
  }

  .fx .el-checkbox:last-of-type {
    margin-right: .3rem;
  }

  .cesium-widget-credits {
    display: none
  }

  .cesium-viewer .cesium-widget-credits {
    display: none
  }

  .custom-mouse-position {
    color: white;
    z-index: 999;
  }

  .ol-tooltip {
    position: relative;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    color: white;
    padding: 4px 8px;
    opacity: 0.7;
    white-space: nowrap;
    font-size: 12px;
  }

  .ol-tooltip-measure {
    opacity: 1;
    font-weight: bold;
  }

  .ol-tooltip-static {
    background-color: #ffcc33;
    color: black;
    border: 1px solid white;
  }

  .ol-tooltip-measure:before,
  .ol-tooltip-static:before {
    border-top: 6px solid rgba(0, 0, 0, 0.5);
    border-right: 6px solid transparent;
    border-left: 6px solid transparent;
    content: "";
    position: absolute;
    bottom: -6px;
    margin-left: -7px;
    left: 50%;
  }

  .ol-tooltip-static:before {
    border-top-color: #ffcc33;
  }
</style>
